package com.springboot.service;

import com.google.code.kaptcha.Constants;
import com.springboot.constant.CommonConstant;
import com.springboot.domain.*;
import com.springboot.dto.*;
import com.springboot.enums.ResultEnum;
import com.springboot.repository.*;
import com.springboot.tools.ResultUtil;
import com.springboot.tools.UUIDTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.transaction.Transactional;
import java.util.*;
import java.util.Date;

@Slf4j
@Service
@Transactional
public class UserService {

    private PersonRepository personRepository;
    private BankRepository bankRepository;
    private EnterpriseRepository enterpriseRepository;
    private UserRepository userRepository;
    private DemandAuthorityRepository demandAuthorityRepository;
    private TaskRepository taskRepository;

    @Autowired
    public UserService(PersonRepository personRepository, BankRepository bankRepository, EnterpriseRepository enterpriseRepository,
                       UserRepository userRepository, DemandAuthorityRepository demandAuthorityRepository, TaskRepository taskRepository) {
        this.personRepository = personRepository;
        this.bankRepository = bankRepository;
        this.enterpriseRepository = enterpriseRepository;
        this.userRepository = userRepository;
        this.demandAuthorityRepository = demandAuthorityRepository;
        this.taskRepository = taskRepository;
    }

    public Result insertUser(Register register, HttpServletRequest request, HttpServletResponse response) {

        String category = register.getCategory();
        String clientCode = register.getClientCode();
        HttpSession session = request.getSession();
        String serverCode = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (clientCode == null || !clientCode.equalsIgnoreCase(serverCode)) {
            log.info("验证码不正确！");
            return ResultUtil.error(ResultEnum.VERIFICATION_CODE_ERROE);
        }
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        if (category == null) {
            return ResultUtil.error(ResultEnum.NullPointerException);
        }

        BtUser user = findUser(register.getName());
        if (user != null) {
            return ResultUtil.error(ResultEnum.EXIST_ERROR);
        }
        session.removeAttribute(Constants.KAPTCHA_SESSION_KEY);
        switch (category) {
            case "person":
                return insertPersonal(register);
            case "enterprise":
                return insertEnterprise(register);
            case "bank":
                return insertBank(register);
            default:
                return ResultUtil.error(ResultEnum.MATCHING_USER_TYPE_ERRPR);
        }
    }

    //验证用户名是否已存在
    private BtUser findUser(String username) {
        return userRepository.findByUserName(username);
    }

    public Result login(Login login, HttpServletRequest request) {

        BtUser user = findUser(login.getName());

        if (null == user) {
            return ResultUtil.error(ResultEnum.NOT_EXIST_ERROR);
        }
        if (user.getStatus().equals(CommonConstant.LOGOUT)) {
            return ResultUtil.error(ResultEnum.ACCOUNTlOGOUT);
        }

        HttpSession session = request.getSession();
        if ((null != session.getAttribute("user")) && (session.getAttribute("user").toString().equals(user.getId()))) {
            return ResultUtil.error(ResultEnum.Repeat_login_Error);
        }
        Result resultPerson = validateUser(user, login);
        if (resultPerson.getABoolean()) {
            session.setAttribute("user", user.getUserId());
            log.info("用户" + login.getName() + "登陆成功！");
            Map<String, String> back = new HashMap<>();
            // 获取用户状态
            String status = getUserStatus(user);
            back.put("userType", user.getUserType());
            back.put("status", status);
            return ResultUtil.success(back);
        }
        return resultPerson;
    }

    private String getUserStatus(BtUser user) {
        if (user.getUserType().equals(CommonConstant.USER_PERSON)) {
            return personRepository.findOne(user.getUserId()).getStatus();
        } else if (user.getUserType().equals(CommonConstant.USER_ENTERPRISE)) {
            return enterpriseRepository.findOne(user.getUserId()).getStatus();
        } else if (user.getUserType().equals(CommonConstant.USER_BANK)) {
            return bankRepository.findOne(user.getUserId()).getStatus();
        }
        return null;
    }

    private Result validateUser(BtUser user, Login login) {
        if (!user.getPassword().equals(login.getPassword())) {
            log.info("用户" + login.getName() + "密码输入错误！");
            return ResultUtil.error(ResultEnum.PASSWORD_ERROR);
        }
        return ResultUtil.success();
    }

    private Result insertPersonal(Register register) {
        // insert person
        String userId = UUIDTool.getUuid();
        BtPerson person = new BtPerson();
        person.setId(userId);
        person.setTel(register.getTel());
        Date time = new Date();
        person.setCreateTime(time);
        person.setStatus(CommonConstant.UNPERFECT);
        person.setEmail(register.getEmail());
        personRepository.save(person);
        // insert user
        saveUser(register, userId, time);
        return ResultUtil.success(ResultEnum.REGISTER_SUCCESS);
    }


    private Result insertEnterprise(Register register) {
        // insert enterprise
        String userId = UUIDTool.getUuid();
        BtEnterprise enterprise = new BtEnterprise();
        enterprise.setId(userId);
        enterprise.setTel(register.getTel());
        enterprise.setEmail(register.getEmail());
        Date time = new Date();
        enterprise.setCreateTime(time);
        enterprise.setStatus(CommonConstant.UNPERFECT);
        enterpriseRepository.save(enterprise);
        // insert user
        saveUser(register, userId, time);
        return ResultUtil.success(ResultEnum.REGISTER_SUCCESS);
    }

    private Result insertBank(Register register) {
        // insert bank
        String userId = UUIDTool.getUuid();
        BtBank bank = new BtBank();
        bank.setId(userId);
        bank.setTel(register.getTel());
        bank.setEmail(register.getEmail());
        Date time = new Date();
        bank.setCreateTime(time);
        bank.setStatus(CommonConstant.UNPERFECT);
        bankRepository.save(bank);
        // insert user
        saveUser(register, userId, time);
        return ResultUtil.success(ResultEnum.REGISTER_SUCCESS);
    }

    private void saveUser(Register register, String userId, Date time) {
        BtUser user = new BtUser();
        user.setId(UUIDTool.getUuid());
        user.setUserId(userId);
        user.setUserType(register.getCategory());
        user.setUserName(register.getName());
        user.setPassword(register.getPassword());
        user.setStatus(CommonConstant.LOGIN);
        user.setCreateTime(time);
        user.setModifyTime(time);
        userRepository.save(user);
    }


    public void logout(String userId) {
        // 根据用户ID 获取用户类型
        BtUser user = userRepository.findByUserId(userId);
        String userType = user.getUserType();
        switch (userType) {
            case CommonConstant.USER_PERSON:
                logoutPerson(userId);
            case CommonConstant.USER_BANK:
                logoutBank(userId);
            case CommonConstant.USER_ENTERPRISE:
                logoutEnterprise(userId);
            default:
                log.info("注销");
        }

    }

    private void logoutEnterprise(String userId) {
        enterpriseRepository.logout(userId);
    }

    private void logoutBank(String userId) {
        bankRepository.logout(userId);
    }

    private void logoutPerson(String userId) {
        personRepository.logout(userId);
    }

    public String updateUserPass(ChangePwdDTO password, HttpSession session) {
        String id = session.getAttribute("user").toString();
        BtUser user = userRepository.findByUserId(id);
        if (user.getPassword().equals(password.getPassword())) {
            user.setPassword(password.getNewPassword());
            userRepository.save(user);
            return "修改密码成功";
        } else {
            return "原密码不正确";
        }
    }

    public String forgetUserPass(ForgetPwdDTO forgetPwdDTO) {
        String username = forgetPwdDTO.getUsername();
        BtUser user = userRepository.findByUserName(username);
        if (user != null) {
            if (user.getStatus().equals(CommonConstant.LOGOUT)) {
                return "此用户已注销，无法修改密码";
            } else if (user.getStatus().equals(CommonConstant.LOGIN)) {
                if (user.getUserType().equals(CommonConstant.USER_BANK)) {
                    BtBank bank = bankRepository.findOne(user.getUserId());
                    if (bank.getEmail().equals(forgetPwdDTO.getEmail()) && bank.getTel().equals(forgetPwdDTO.getTel())) {
                        user.setPassword(forgetPwdDTO.getNewPassword());
                        userRepository.save(user);
                    } else {
                        return "邮箱或电话号码不正确";
                    }
                } else if (user.getUserType().equals(CommonConstant.USER_ENTERPRISE)) {
                    BtEnterprise enterprise = enterpriseRepository.findOne(user.getUserId());
                    if (enterprise.getEmail().equals(forgetPwdDTO.getEmail()) && enterprise.getTel().equals(forgetPwdDTO.getTel())) {
                        user.setPassword(forgetPwdDTO.getNewPassword());
                        userRepository.save(user);
                    } else {
                        return "邮箱或电话号码不正确";
                    }
                } else if (user.getUserType().equals(CommonConstant.USER_PERSON)) {
                    BtPerson person = personRepository.findOne(user.getUserId());
                    if (person.getEmail().equals(forgetPwdDTO.getEmail()) && person.getTel().equals(forgetPwdDTO.getTel())) {
                        user.setPassword(forgetPwdDTO.getNewPassword());
                        userRepository.save(user);
                    } else {
                        return "邮箱或电话号码不正确";
                    }
                }
            }
        } else {
            return "该用户名不存在，无法修改密码";
        }
        return "修改密码成功";
    }

    public UserInUnInProjectDTO findUserInProjectAndNot(String id) {
        List<BtDemandAuthority> demandAuthorities = demandAuthorityRepository.findByDemandId(id);
        List<String> usersId = new ArrayList<>();
        for (BtDemandAuthority authority : demandAuthorities) {
            usersId.add(authority.getUserId());
        }
        UserInUnInProjectDTO userInUnInProjectDTO = new UserInUnInProjectDTO();
        List<BtUser> notInUser = userRepository.findUserNotInProject(usersId);
        List<BtUser> inProjectUser = new ArrayList<>();
        for (String userId : usersId) {
            BtUser inUser = userRepository.findByUserId(userId);
            inProjectUser.add(inUser);
        }
        userInUnInProjectDTO.setInProject(inProjectUser);
        userInUnInProjectDTO.setNotInProject(notInUser);
        return userInUnInProjectDTO;
    }

    public Result<List<SuRecordDTO>> findUserSuRecord(String userId) {
        List<SuRecordDTO> list = taskRepository.findUserSuRecord(userId);
        if (list.size() == 0) {
            return ResultUtil.error("暂无该用户成功交易记录");
        }
        return ResultUtil.success(list);
    }


}